home *** CD-ROM | disk | FTP | other *** search
/ Risc World 5 / Risc World 5.iso / SOFTWARE / Issue5 / PD / DIRSYNC / LegalStuff / ccres / c / _Window < prev    next >
Text File  |  2004-03-20  |  23KB  |  402 lines

  1. /* _Window.c
  2.    $Id: _Window.c,v 1.2 2004/03/20 22:13:56 joty Exp $
  3.  
  4.    Copyright (c) 2003-2004 Dave Appleby / John Tytgat
  5.  
  6.    This file is part of CCres.
  7.  
  8.    CCres is free software; you can redistribute it and/or modify
  9.    it under the terms of the GNU General Public License as published by
  10.    the Free Software Foundation; either version 2 of the License, or
  11.    (at your option) any later version.
  12.  
  13.    CCres is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    GNU General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with CCres; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21.  */
  22.  
  23. #include "ccres.h"
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27.  
  28. #include <OSLib/toolbox.h>
  29. #include <OSLib/window.h>
  30.  
  31. #include <OSLib/actionbutton.h>
  32. #include <OSLib/adjuster.h>
  33. #include <OSLib/button.h>
  34. #include <OSLib/displayfield.h>
  35. #include <OSLib/draggable.h>
  36. #include <OSLib/keyboardshortcut.h>
  37. #include <OSLib/label.h>
  38. #include <OSLib/labelledbox.h>
  39. #include <OSLib/numberrange.h>
  40. #include <OSLib/optionbutton.h>
  41. #include <OSLib/popup.h>
  42. #include <OSLib/radiobutton.h>
  43. #include <OSLib/scrolllist.h>
  44. #include <OSLib/slider.h>
  45. #include <OSLib/stringset.h>
  46. #include <OSLib/textarea.h>
  47. #include <OSLib/textgadgets.h>
  48. #include <OSLib/toolaction.h>
  49. #include <OSLib/writablefield.h>
  50.  
  51. static GADGETS Gadgets[] = {
  52.     {class_ACTION_BUTTON,  actionbutton,  _actionbutton,  "actionbutton_object" },
  53.     {class_ADJUSTER,       adjuster,      _adjuster,      "adjuster_object"     },
  54.     {class_BUTTON,         button,        _button,        "button_object"       },
  55.     {class_DISPLAY_FIELD,  displayfield,  _displayfield,  "displayfield_object" },
  56.     {class_DRAGGABLE,      draggable,     _draggable,     "draggable_object"    },
  57.     {class_LABEL,          label,         _label,         "label_object"        },
  58.     {class_LABELLED_BOX,   labelledbox,   _labelledbox,   "labelledbox_object"  },
  59.     {class_NUMBER_RANGE,   numberrange,   _numberrange,   "numberrange_object"  },
  60.     {class_OPTION_BUTTON,  optionbutton,  _optionbutton,  "optionbutton_object" },
  61.     {class_POP_UP,         popup,         _popup,         "popup_object"        },
  62.     {class_RADIO_BUTTON,   radiobutton,   _radiobutton,   "radiobutton_object"  },
  63.     {class_SCROLL_LIST,    scrolllist,    _scrolllist,    "scrolllist_object"   },
  64.     {class_SLIDER,         slider,        _slider,        "slider_object"       },
  65.     {class_STRING_SET,     stringset,     _stringset,     "stringset_object"    },
  66.     {class_TEXT_AREA,      textarea,      _textarea,      "textarea_object"     },
  67.     {class_TOOL_ACTION,    toolaction,    _toolaction,    "toolaction_object"   },
  68.     {class_WRITABLE_FIELD, writablefield, _writablefield, "writablefield_object"}
  69. };
  70.  
  71. static FLAGS WindowFlags[] = {
  72.     {window_GENERATE_ABOUT_TO_BE_SHOWN , "window_GENERATE_ABOUT_TO_BE_SHOWN" },
  73.     {window_AUTO_OPEN                  , "window_AUTO_OPEN"                  },
  74.     {window_AUTO_CLOSE                 , "window_AUTO_CLOSE"                 },
  75.     {window_GENERATE_DIALOGUE_COMPLETED, "window_GENERATE_DIALOGUE_COMPLETED"},
  76.     {window_IS_TOOL_BAR                , "window_IS_TOOL_BAR"                }
  77. };
  78.  
  79. static FLAGS WindowWindowFlags[] = {
  80.     {wimp_WINDOW_MOVEABLE         , "wimp_WINDOW_MOVEABLE"         },
  81.     {wimp_WINDOW_AUTO_REDRAW      , "wimp_WINDOW_AUTO_REDRAW"      },
  82.     {wimp_WINDOW_PANE             , "wimp_WINDOW_PANE"             },
  83.     {wimp_WINDOW_NO_BOUNDS        , "wimp_WINDOW_NO_BOUNDS"        },
  84.     {wimp_WINDOW_SCROLL_REPEAT    , "wimp_WINDOW_SCROLL_REPEAT"    },
  85.     {wimp_WINDOW_SCROLL           , "wimp_WINDOW_SCROLL"           },
  86.     {wimp_WINDOW_REAL_COLOURS     , "wimp_WINDOW_REAL_COLOURS"     },
  87.     {wimp_WINDOW_BACK             , "wimp_WINDOW_BACK"             },
  88.     {wimp_WINDOW_HOT_KEYS         , "wimp_WINDOW_HOT_KEYS"         },
  89.     {wimp_WINDOW_BOUNDED          , "wimp_WINDOW_BOUNDED"          },
  90.     {wimp_WINDOW_IGNORE_XEXTENT   , "wimp_WINDOW_IGNORE_XEXTENT"   },
  91.     {wimp_WINDOW_IGNORE_YEXTENT   , "wimp_WINDOW_IGNORE_YEXTENT"   },
  92.     {wimp_WINDOW_OPEN             , "wimp_WINDOW_OPEN"             },
  93.     {wimp_WINDOW_NOT_COVERED      , "wimp_WINDOW_NOT_COVERED"      },
  94.     {wimp_WINDOW_FULL_SIZE        , "wimp_WINDOW_FULL_SIZE"        },
  95.     {wimp_WINDOW_TOGGLED          , "wimp_WINDOW_TOGGLED"          },
  96.     {wimp_WINDOW_HAS_FOCUS        , "wimp_WINDOW_HAS_FOCUS"        },
  97.     {wimp_WINDOW_BOUNDED_ONCE     , "wimp_WINDOW_BOUNDED_ONCE"     },
  98.     {wimp_WINDOW_PARTIAL_SIZE     , "wimp_WINDOW_PARTIAL_SIZE"     },
  99.     {wimp_WINDOW_FURNITURE_WINDOW , "wimp_WINDOW_FURNITURE_WINDOW" },
  100.     {wimp_WINDOW_FOREGROUND_WINDOW, "wimp_WINDOW_FOREGROUND_WINDOW"},
  101.     {wimp_WINDOW_BACK_ICON        , "wimp_WINDOW_BACK_ICON"        },
  102.     {wimp_WINDOW_CLOSE_ICON       , "wimp_WINDOW_CLOSE_ICON"       },
  103.     {wimp_WINDOW_TITLE_ICON       , "wimp_WINDOW_TITLE_ICON"       },
  104.     {wimp_WINDOW_TOGGLE_ICON      , "wimp_WINDOW_TOGGLE_ICON"      },
  105.     {wimp_WINDOW_VSCROLL          , "wimp_WINDOW_VSCROLL"          },
  106.     {wimp_WINDOW_SIZE_ICON        , "wimp_WINDOW_SIZE_ICON"        },
  107.     {wimp_WINDOW_HSCROLL          , "wimp_WINDOW_HSCROLL"          },
  108.     {wimp_WINDOW_NEW_FORMAT       , "wimp_WINDOW_NEW_FORMAT"       }
  109. };
  110.  
  111. static FLAGS WindowExtraFlags[] = {
  112.     {wimp_WINDOW_USE_TITLE_VALIDATION_COLOURS, "wimp_WINDOW_USE_TITLE_VALIDATION_COLOURS"},
  113.     {wimp_WINDOW_USE_TITLE_VALIDATION_STRING , "wimp_WINDOW_USE_TITLE_VALIDATION_STRING" },
  114.     {wimp_WINDOW_USE_EXTENDED_SCROLL_REQUEST , "wimp_WINDOW_USE_EXTENDED_SCROLL_REQUEST" },
  115.     {wimp_WINDOW_NEVER3D                     , "wimp_WINDOW_NEVER3D"                     },
  116.     {wimp_WINDOW_ALWAYS3D                    , "wimp_WINDOW_ALWAYS3D"                    }
  117. };
  118.  
  119. static FLAGS WindowTitleFlags[] = {
  120.     {wimp_ICON_TEXT               , "wimp_ICON_TEXT"               },
  121.     {wimp_ICON_SPRITE             , "wimp_ICON_SPRITE"             },
  122.     {wimp_ICON_BORDER             , "wimp_ICON_BORDER"             },
  123.     {wimp_ICON_HCENTRED           , "wimp_ICON_HCENTRED"           },
  124.     {wimp_ICON_VCENTRED           , "wimp_ICON_VCENTRED"           },
  125.     {wimp_ICON_FILLED             , "wimp_ICON_FILLED"             },
  126.     {wimp_ICON_ANTI_ALIASED       , "wimp_ICON_ANTI_ALIASED"       },
  127.     {wimp_ICON_INDIRECTED         , "wimp_ICON_INDIRECTED"         },
  128.     {wimp_ICON_RJUSTIFIED         , "wimp_ICON_RJUSTIFIED"         },
  129.     {wimp_ICON_ALLOW_ADJUST       , "wimp_ICON_ALLOW_ADJUST"       },
  130.     {wimp_ICON_HALF_SIZE          , "wimp_ICON_HALF_SIZE"          },
  131.     {wimp_ICON_SELECTED           , "wimp_ICON_SELECTED"           },
  132.     {wimp_ICON_SHADED             , "wimp_ICON_SHADED"             }
  133. };
  134.  
  135. static FLAGS WindowWorkFlags[] = {
  136.     {(wimp_BUTTON_ALWAYS            << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_ALWAYS"           },
  137.     {(wimp_BUTTON_REPEAT            << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_REPEAT"           },
  138.     {(wimp_BUTTON_CLICK             << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_CLICK"            },
  139.     {(wimp_BUTTON_RELEASE           << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_RELEASE"          },
  140.     {(wimp_BUTTON_DOUBLE_CLICK      << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_DOUBLE_CLICK"     },
  141.     {(wimp_BUTTON_CLICK_DRAG        << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_CLICK_DRAG"       },
  142.     {(wimp_BUTTON_RELEASE_DRAG      << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_RELEASE_DRAG"     },
  143.     {(wimp_BUTTON_DOUBLE_DRAG       << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_DOUBLE_DRAG"      },
  144.     {(wimp_BUTTON_MENU_ICON         << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_MENU_ICON"        },
  145.     {(wimp_BUTTON_DOUBLE_CLICK_DRAG << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_DOUBLE_CLICK_DRAG"},
  146.     {(wimp_BUTTON_RADIO             << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_RADIO"            },
  147.     {(wimp_BUTTON_WRITE_CLICK_DRAG  << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_WRITE_CLICK_DRAG" },
  148.     {(wimp_BUTTON_WRITABLE          << wimp_ICON_BUTTON_TYPE_SHIFT), "wimp_BUTTON_WRITABLE"         }
  149. };
  150.  
  151. static FLAGS WindowNextFlags[] = {
  152.     {(int) wimp_TOP   , "wimp_TOP"   },
  153.     {(int) wimp_BOTTOM, "wimp_BOTTOM"},
  154.     {(int) wimp_HIDDEN, "wimp_HIDDEN"}
  155. };
  156.  
  157. static OBJECTLIST WindowObjectList[] = {
  158.     {iol_FLAGS,  "window_flags:",            offsetof(window_object_base, flags),               WindowFlags,       ELEMENTS(WindowFlags)                   },
  159.     {iol_MSG,    "help_message:",            offsetof(window_object_base, help_message),        "help_limit:",     offsetof(window_object_base, help_limit)},
  160.     {iol_STRING, "sprite_name:",             offsetof(window_object_base, sprite_name),         NULL,              0                                       },
  161.     {iol_INT,    "pointer_limit:",           offsetof(window_object_base, pointer_limit),       NULL,              0                                       },
  162.     {iol_COORD,  "hotspot:",                 offsetof(window_object_base, hotspot),             NULL,              0                                       },
  163.     {iol_STRING, "menu_name:",               offsetof(window_object_base, menu_name),           NULL,              0                                       },
  164.     {iol_OBJECT, "shortcuts:",               offsetof(window_object_base, shortcuts),           NULL,              0                                       },
  165.     {iol_OBJECT, "gadgets:",                 offsetof(window_object_base, gadgets),             NULL,              0                                       },
  166.     {iol_CMP,    "default_focus:",           offsetof(window_object_base, default_focus),       NULL,              0                                       },
  167.     {iol_BITS,   "show_action:",             offsetof(window_object_base, show_action),         NULL,              bits_ACTION                             },
  168.     {iol_BITS,   "hide_action:",             offsetof(window_object_base, hide_action),         NULL,              bits_ACTION                             },
  169.     {iol_STRING, "toolbar_ibl:",             offsetof(window_object_base, toolbar_ibl),         NULL,              0                                       },
  170.     {iol_STRING, "toolbar_itl:",             offsetof(window_object_base, toolbar_itl),         NULL,              0                                       },
  171.     {iol_STRING, "toolbar_ebl:",             offsetof(window_object_base, toolbar_ebl),         NULL,              0                                       },
  172.     {iol_STRING, "toolbar_etl:",             offsetof(window_object_base, toolbar_etl),         NULL,              0                                       },
  173.     {iol_BOX,    "window.visible:",          offsetof(window_object_base, window.visible),      NULL,              0                                       },
  174.     {iol_INT,    "window.xscroll:",          offsetof(window_object_base, window.xscroll),      NULL,              0                                       },
  175.     {iol_INT,    "window.yscroll:",          offsetof(window_object_base, window.yscroll),      NULL,              0                                       },
  176.     {iol_ENUM,   "window.next:",             offsetof(window_object_base, window.next),         WindowNextFlags,   ELEMENTS(WindowNextFlags)               },
  177.     {iol_FLAGS,  "window.flags:",            offsetof(window_object_base, window.flags),        WindowWindowFlags, ELEMENTS(WindowWindowFlags)             },
  178.     {iol_WCOL,   "window.title_fg:",         offsetof(window_object_base, window.title_fg),     NULL,              0                                       },
  179.     {iol_WCOL,   "window.title_bg:",         offsetof(window_object_base, window.title_bg),     NULL,              0                                       },
  180.     {iol_WCOL,   "window.work_fg:",          offsetof(window_object_base, window.work_fg),      NULL,              0                                       },
  181.     {iol_WCOL,   "window.work_bg:",          offsetof(window_object_base, window.work_bg),      NULL,              0                                       },
  182.     {iol_WCOL,   "window.scroll_outer:",     offsetof(window_object_base, window.scroll_outer), NULL,              0                                       },
  183.     {iol_WCOL,   "window.scroll_inner:",     offsetof(window_object_base, window.scroll_inner), NULL,              0                                       },
  184.     {iol_WCOL,   "window.highlight_bg:",     offsetof(window_object_base, window.highlight_bg), NULL,              0                                       },
  185.     {iol_BFLAGS, "window.extra_flags:",      offsetof(window_object_base, window.extra_flags),  WindowExtraFlags,  ELEMENTS(WindowExtraFlags)              },
  186.     {iol_BOX,    "window.extent:",           offsetof(window_object_base, window.extent),       NULL,              0                                       },
  187.     {iol_FLAGS,  "window.title_flags:",      offsetof(window_object_base, window.title_flags),  WindowTitleFlags,  ELEMENTS(WindowTitleFlags)              },
  188.     {iol_FLAGS,  "window.work_flags:",       offsetof(window_object_base, window.work_flags),   WindowWorkFlags,   ELEMENTS(WindowWorkFlags)               },
  189.     {iol_SPRITE, "window.sprite_area:",      offsetof(window_object_base, window.sprite_area),  NULL,              0                                       },
  190.     {iol_SHORT,  "window.xmin:",             offsetof(window_object_base, window.xmin),         NULL,              0                                       },
  191.     {iol_SHORT,  "window.ymin:",             offsetof(window_object_base, window.ymin),         NULL,              0                                       },
  192.     {iol_MSG,    "window.title_text:",       offsetof(window_object_base, window.title_data.indirected_text.text),
  193.                  "window.title_text_limit:", offsetof(window_object_base, window.title_data.indirected_text.size)                                          },
  194.     {iol_STRING, "window.title_valid:",      offsetof(window_object_base, window.title_data.indirected_text.validation), NULL, 0                           }
  195. };
  196.  
  197. static OBJECTLIST GadgetHeaderList[] = {
  198.     {iol_BITS, "cmp:",          offsetof(gadget_object, cmp),          NULL,          bits_EVAL                          },
  199.     {iol_BOX,  "bbox:",         offsetof(gadget_object, bbox),         NULL,          0                                  },
  200.     {iol_MSG,  "help_message:", offsetof(gadget_object, help_message), "help_limit:", offsetof(gadget_object, help_limit)}
  201. };
  202.  
  203. static PSTR pszShortcutObject = "keyboardshortcut_object";
  204. static FLAGS ShortcutFlags[] = {
  205.     {keyboardshortcut_SHOW_AS_MENU   , "keyboardshortcut_SHOW_AS_MENU"   },
  206.     {keyboardshortcut_SHOW_AT_CENTRE , "keyboardshortcut_SHOW_AT_CENTRE" },
  207.     {keyboardshortcut_SHOW_AT_POINTER, "keyboardshortcut_SHOW_AT_POINTER"}
  208. };
  209.  
  210. static OBJECTLIST ShortcutList[] = {
  211.     {iol_FLAGS,  "flags:",     offsetof(keyboardshortcut_object, flags),  ShortcutFlags, ELEMENTS(ShortcutFlags)},
  212.     {iol_BITS,   "key_code:",  offsetof(keyboardshortcut_object, c),      NULL,          0                      },
  213.     {iol_BITS,   "key_event:", offsetof(keyboardshortcut_object, action), NULL,          0                      },
  214.     {iol_STRING, "key_show:",  offsetof(keyboardshortcut_object, name),   NULL,          0                      }
  215. };
  216.  
  217.  
  218. int _window(PDATA data, PSTR pszIn, toolbox_relocatable_object_base * object)
  219. {
  220.     window_object_base * window_object;
  221.     keyboardshortcut_object * shortcut;
  222.     gadget_object_base * gadget;
  223.     PSTR pszObject, pszShortcut, pszEnd;
  224.     int shortcut_count, g, gadget_count, nOffset, nSize;
  225.  
  226.     window_object = (window_object_base *) (object + 1);
  227.     put_objects(data, pszIn, 0, (PSTR) window_object, WindowObjectList, ELEMENTS(WindowObjectList));
  228.  
  229.     pszEnd = data->pszIn + data->cbIn;
  230.     pszShortcut = pszIn;
  231.     shortcut = (keyboardshortcut_object *) ((PSTR) window_object + sizeof(window_object_base));
  232.     shortcut_count = 0;
  233.     while ((pszObject = next_object(&pszShortcut, pszEnd)) != NULL) {
  234.         if (__stricmp(pszShortcutObject, pszObject) == 0) {
  235.             nOffset = (int) ((PSTR) shortcut - (PSTR) window_object);
  236.             put_objects(data, pszShortcut, nOffset, (PSTR) shortcut, ShortcutList, ELEMENTS(ShortcutList));
  237.             shortcut++;
  238.             shortcut_count++;
  239.         }
  240.         if ((pszShortcut = object_end(data, pszShortcut, pszEnd)) == NULL) {
  241.             break;
  242.         }
  243.     }
  244.     if (shortcut_count > 0) {
  245.         window_object->shortcut_count = shortcut_count;
  246.         window_object->shortcuts = (toolbox_object_offset) sizeof(window_object_base);
  247.     } else {
  248.         window_object->shortcuts = (toolbox_object_offset) -1;
  249.     }
  250.  
  251.     gadget = (gadget_object_base *) shortcut;
  252.     gadget_count = 0;
  253.     while ((pszObject = next_object(&pszIn, pszEnd)) != NULL) {
  254. LOG(("_window pszObject=%s @ %p", pszObject, gadget));
  255.         for (g = 0; g < ELEMENTS(Gadgets); g++) {
  256.             if (__stricmp(Gadgets[g].name, pszObject) == 0) {
  257.                 nOffset = (int) ((PSTR) gadget - (PSTR) window_object);
  258.                 put_objects(data, pszIn, nOffset, (PSTR) gadget, GadgetHeaderList, ELEMENTS(GadgetHeaderList));
  259.                 nSize = Gadgets[g].t2g(data, pszIn, nOffset, gadget);
  260.                 gadget->class_no_and_size = (nSize << 16) | Gadgets[g].class_no;
  261.                 gadget = (gadget_object_base *) ((PSTR) gadget + nSize);
  262.                 gadget_count++;
  263. LOG(("size=%d next object @ %p", nSize, gadget));
  264.                 goto _window_gadget_added;
  265.             }
  266.         }
  267.         if (__stricmp(pszShortcutObject, pszObject) != 0) {
  268.             error("Unhandled gadget class '%s'", pszObject);
  269.         }
  270.  
  271. _window_gadget_added:
  272.  
  273.         if ((pszIn = object_end(data, pszIn, pszEnd)) == NULL) {
  274.             break;
  275.         }
  276.     }
  277.     if (gadget_count > 0) {
  278.         window_object->gadget_count = gadget_count;
  279.         window_object->gadgets = (toolbox_object_offset) ((PSTR) sizeof(window_object_base) + (shortcut_count * sizeof(keyboardshortcut_object)));
  280.     } else {
  281.         window_object->gadgets = (toolbox_object_offset) -1;
  282.     }
  283.     return((int) ((PSTR) gadget - (PSTR) window_object));
  284. }
  285.  
  286.  
  287. void window(FILE * hf, toolbox_resource_file_object_base * object, PSTR pszStringTable, PSTR pszMessageTable)
  288. {
  289.     window_object_base * window_object;
  290.     gadget_object_base * gadget;
  291.     keyboardshortcut_object * shortcut;
  292.     int n, g, nSize, nClass;
  293.  
  294.     window_object = (window_object_base *) (object + 1);
  295.     get_objects(hf, pszStringTable, pszMessageTable, (PSTR) window_object, WindowObjectList, ELEMENTS(WindowObjectList), 1);
  296.  
  297.     shortcut = (keyboardshortcut_object *) ((PSTR) window_object + (int) window_object->shortcuts);
  298.     for (n = 0; n < window_object->shortcut_count; n++, shortcut++) {
  299.         fprintf(hf, "  %s {\n", pszShortcutObject);
  300.         get_objects(hf, pszStringTable, pszMessageTable, (PSTR) shortcut, ShortcutList, ELEMENTS(ShortcutList), 2);
  301.         fputs("  }\n", hf);
  302.     }
  303.  
  304.     gadget = (gadget_object_base *) ((PSTR) window_object + (int) window_object->gadgets);
  305.     for (n = 0; n < window_object->gadget_count; n++) {
  306.         nSize = (gadget->class_no_and_size >> 16);
  307.         nClass = (gadget->class_no_and_size & 0xffff);
  308.         for (g = 0; g < ELEMENTS(Gadgets); g++) {
  309.             if (Gadgets[g].class_no == nClass) {
  310. LOG((Gadgets[g].name));
  311.                 fprintf(hf, "  %s {\n", Gadgets[g].name);
  312.                 get_objects(hf, pszStringTable, pszMessageTable, (PSTR) gadget, GadgetHeaderList, ELEMENTS(GadgetHeaderList), 2);
  313.                 Gadgets[g].g2t(hf, gadget, pszStringTable, pszMessageTable);
  314.                 fputs("  }\n", hf);
  315. LOG((""));
  316.                 goto window_gadget_added;
  317.             }
  318.         }
  319.         error("Unhandled gadget class &%x size %d", nClass, nSize);
  320.  
  321. window_gadget_added:
  322.  
  323.         gadget = (gadget_object_base *) ((char *) gadget + nSize);
  324.     }
  325. }
  326.  
  327. //=================================== Template window handlers ======================================
  328. // a separate source file wuold have been nice, but sharing common data tricky without duplication...
  329.  
  330.  
  331. static OBJECTLIST WimpWindowObjectList[] = {
  332.     {iol_BOX,    "visible:",      offsetof(wimp_window_base, visible),      NULL,              0                          },
  333.     {iol_INT,    "xscroll:",      offsetof(wimp_window_base, xscroll),      NULL,              0                          },
  334.     {iol_INT,    "yscroll:",      offsetof(wimp_window_base, yscroll),      NULL,              0                          },
  335.     {iol_ENUM,   "next:",         offsetof(wimp_window_base, next),         WindowNextFlags,   ELEMENTS(WindowNextFlags)  },
  336.     {iol_FLAGS,  "window_flags:", offsetof(wimp_window_base, flags),        WindowWindowFlags, ELEMENTS(WindowWindowFlags)},
  337.     {iol_WCOL,   "title_fg:",     offsetof(wimp_window_base, title_fg),     NULL,              0                          },
  338.     {iol_WCOL,   "title_bg:",     offsetof(wimp_window_base, title_bg),     NULL,              0                          },
  339.     {iol_WCOL,   "work_fg:",      offsetof(wimp_window_base, work_fg),      NULL,              0                          },
  340.     {iol_WCOL,   "work_bg:",      offsetof(wimp_window_base, work_bg),      NULL,              0                          },
  341.     {iol_WCOL,   "scroll_outer:", offsetof(wimp_window_base, scroll_outer), NULL,              0                          },
  342.     {iol_WCOL,   "scroll_inner:", offsetof(wimp_window_base, scroll_inner), NULL,              0                          },
  343.     {iol_WCOL,   "highlight_bg:", offsetof(wimp_window_base, highlight_bg), NULL,              0                          },
  344.     {iol_BFLAGS, "extra_flags:",  offsetof(wimp_window_base, extra_flags),  WindowExtraFlags,  ELEMENTS(WindowExtraFlags) },
  345.     {iol_BOX,    "extent:",       offsetof(wimp_window_base, extent),       NULL,              0                          },
  346.     {iol_FLAGS,  "title_flags:",  offsetof(wimp_window_base, title_flags),  WindowTitleFlags,  ELEMENTS(WindowTitleFlags) },
  347.     {iol_ENUM,   "work_flags:",   offsetof(wimp_window_base, work_flags),   WindowWorkFlags,   ELEMENTS(WindowWorkFlags)  },
  348.     {iol_BITS,   "sprite_area:",  offsetof(wimp_window_base, sprite_area),  NULL,              0                          },
  349.     {iol_SHORT,  "xmin:",         offsetof(wimp_window_base, xmin),         NULL,              0                          },
  350.     {iol_SHORT,  "ymin:",         offsetof(wimp_window_base, ymin),         NULL,              0                          }
  351. };
  352.  
  353.  
  354. int _window_template(PDATA data, PSTR pszIn, int nOffset, wimp_window_base * window)
  355. {
  356.     wimp_icon * icon;
  357.     PSTR pszObject, pszEnd, strings;
  358.     int ref;
  359.  
  360.     put_objects(data, pszIn, 0, (PSTR) window, WimpWindowObjectList, ELEMENTS(WimpWindowObjectList));
  361.     put_icon_data(data, pszIn, nOffset, (wimp_icon_data *) &window->title_data, window->title_flags);
  362.  
  363.     pszEnd = data->pszIn + data->cbIn;
  364.     icon = (wimp_icon *) (window + 1);
  365.     while ((pszObject = next_object(&pszIn, pszEnd)) != NULL) {
  366. LOG(("_window pszObject=%s offset=%d (%x)", pszObject, -nOffset, -nOffset));
  367.         _icon(data, pszIn, nOffset, icon);
  368.         icon++;
  369.         if ((pszIn = object_end(data, pszIn, pszEnd)) == NULL) {
  370.             break;
  371.         }
  372.     }
  373.     window->icon_count = (int) ((PSTR) icon - (PSTR) (window + 1)) / sizeof(wimp_icon);
  374.  
  375.     strings = (PSTR) icon;
  376.     if ((ref = data->StringTable.ref) > 0) {
  377.         memcpy(strings, data->StringTable.pstr, ref);
  378.         strings += ref;
  379.         reset_string_table(&data->StringTable);
  380.     }
  381.     return((int) (strings - (PSTR) window));
  382. }
  383.  
  384.  
  385. void window_template(FILE * hf, PSTR pszBuff)
  386. {
  387.     wimp_window_base * window;
  388.     wimp_icon * i;
  389.     int n;
  390.  
  391.     window = (wimp_window_base *) pszBuff;
  392.     get_objects(hf, pszBuff, NULL, (PSTR) window, WimpWindowObjectList, ELEMENTS(WimpWindowObjectList), 1);
  393.     get_icon_data(hf, pszBuff, (wimp_icon_data *) &window->title_data, window->title_flags, 1);
  394.  
  395.     i = (wimp_icon *) (window + 1);
  396.     for (n = 0; n < window->icon_count; n++, i++) {
  397.         fputs("  wimp_icon {\n", hf);
  398.         icon(hf, pszBuff, i);
  399.         fputs("  }\n", hf);
  400.     }
  401. }
  402.